package com.cardone.persistent.aspect;

import com.cardone.context.ContextHolder;
import com.cardone.persistent.support.RedundancyUpdateAction;
import com.cardone.persistent.support.UpdateAction;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;

import java.util.Collection;
import java.util.Map;

/**
 * Created by Administrator on 2014/11/1.
 */
@lombok.extern.slf4j.Slf4j
public class RedundancyAspect {
    Multimap<String, UpdateAction> redundancyUpdateActionMap;

    /**
     * 批量处理
     *
     * @param joinPoint
     */
    public void batchUpdate(final org.aspectj.lang.JoinPoint joinPoint) {
        this.init();

        if (redundancyUpdateActionMap.size() < 1) {
            return;
        }

        String key = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName();

        redundancyUpdateActionRun(key);
    }

    public void redundancyUpdateActionRun(String key) {
        if (redundancyUpdateActionMap.size() < 1) {
            return;
        }

        if (!redundancyUpdateActionMap.containsKey(key)) {
            return;
        }

        Collection<UpdateAction> updateActions = redundancyUpdateActionMap.get(key);

        if (CollectionUtils.isEmpty(updateActions)) {
            return;
        }

        for (UpdateAction updateAction : updateActions) {
            try {
                updateAction.run();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    private void init() {
        if (redundancyUpdateActionMap != null) {
            return;
        }

        redundancyUpdateActionMap = HashMultimap.create();

        Map<String, RedundancyUpdateAction> redundancyUpdateActions = ContextHolder.getApplicationContext().getBeansOfType(RedundancyUpdateAction.class);

        this.initRedundancyUpdateActionMap(redundancyUpdateActions);
    }

    private void initRedundancyUpdateActionMap(Map<String, RedundancyUpdateAction> redundancyUpdateActions) {
        if (MapUtils.isEmpty(redundancyUpdateActions)) {
            return;
        }

        for (Map.Entry<String, RedundancyUpdateAction> redundancyUpdateActionsEntry : redundancyUpdateActions.entrySet()) {
            if (ArrayUtils.isEmpty(redundancyUpdateActionsEntry.getValue().getNames())) {
                continue;
            }

            for (String redundancyUpdateActionKey : redundancyUpdateActionsEntry.getValue().getNames()) {
                redundancyUpdateActionMap.put(redundancyUpdateActionKey, redundancyUpdateActionsEntry.getValue());
            }
        }
    }
}

